#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "../Common/AceptadorCnx.h"
#include "../Common/ConectorCnx.h"
#include "../Common/mensaje.h"
#include "Interfaz/TableroSDL.h"
#include "Interfaz/CeldaSDL.h"
#include "Interfaz/MovementHandler.h"
#include "SDL/SDL_mixer.h"
#include "SDL/SDL_ttf.h"
#include "Interfaz/LoginInterfaz.h"
#include <vector>
#include <gtkmm.h>

using std::string;
using std::vector;

void* enviar(void* puntero){
	SDL_Event event;
	bool quit = false;
	Mix_Music *music = NULL;
	music = Mix_LoadMUS("Sonidos/musica.wav");
	Mix_PlayMusic(music, -1);
	Json::Value msjJson;
	MovementHandler* handler = (MovementHandler*)(puntero);
	while(quit == false){
		msjJson.clear();
		while(SDL_PollEvent(&event)){
			if(event.type == SDL_QUIT){
				quit = true;
				msjJson["flag"] = "q";
				handler->getStream()->send(msjJson.toStyledString());
				handler->setTerminar(true);
			} else if (!handler->getBloqueo()){
				if(event.type == SDL_MOUSEMOTION){
					handler->ubicarMouse(event.motion.x, event.motion.y);
				}else if (event.type == SDL_MOUSEBUTTONDOWN){
					handler->pulsaGolosina();
				}else if (event.type == SDL_MOUSEBUTTONUP){
					handler->soltarGolosina();
				}
			}
		}
		if(handler->getTablero()->hayJugadas()
						&& handler->getTablero()->getDibujarJugadas()){
			handler->getTablero()->dibujarSinFondo();
		}
		if(handler->getTerminar()){
			if (handler->getGano()){
				handler->getTablero()->setFondo("Imagenes/ganaste.png");
				SDL_Delay(300);
			}else{
				handler->getTablero()->setFondo("Imagenes/perdiste.png");
				SDL_Delay(300);
			}
			quit = true;
		}
		handler->getTablero()->dibujar(handler->getTerminar());
	}
	Mix_FreeMusic(music);
	return 0;
}

void* recibir(void* puntero){
	MovementHandler* handler = (MovementHandler*)(puntero);
	bool quit = false;
	bool resultado = false;
	string mensaje;
	string flag;
	Json::Value resultados;
	Mensaje msj;
	while (!quit && !handler->getTerminar()){
		mensaje = handler->getStream()->receive();
		resultados = msj.convertJson(mensaje);
		flag = resultados["flag"].asString();
		if (flag.compare("j") == 0){
			handler->setJsonMov(resultados);
			resultado = resultados["valido"].asBool();
			if (!resultado){
				handler->intercambiar(resultados["celda1"].asInt(),
						resultados["celda2"].asInt());
			}else{
				for(Json::Value::iterator it = resultados["jugadas"].begin();
						it != resultados["jugadas"].end(); ++it){
					handler->eliminarYRellenarPosiciones(*it);
				}
				handler->getTablero()->habilitarDibujarJugadas();
				handler->getTablero()->actualizarPuntajes(
											resultados["puntajes"]);
			}
			handler->setBloqueo(false);
		}else if (flag.compare("q") == 0){
			quit = true;
			handler->setTerminar(true);
		}else if (flag.compare("b") == 0){
			handler->setBloqueo(true);
			if (resultados["intercambio"].asBool()){
				handler->intercambiar(resultados["celda1"].asInt(),
						resultados["celda2"].asInt());
			}
		}else if (flag.compare("ganaste") == 0){
			handler->setBloqueo(true);
			handler->setGano(true);
			handler->setTerminar(true);
		}else if (flag.compare("perdiste") == 0){
			handler->setBloqueo(true);
			handler->setGano(false);
			handler->setTerminar(true);
		}
	}
	return 0;
}


bool loguear(Conexion* stream,Gtk::Main kit, std::string & key){
	bool exito;
    LoginInterfaz logInterfaz(stream, kit);
    logInterfaz.logInit();
    logInterfaz.pedirLogin();
    exito =  logInterfaz.logueoExitoso();
    key = logInterfaz.getPass();
//    if (exito){
//    	logInterfaz.pasarAEspera();
//    }
    return exito;
}


void jugar(Conexion* stream, const string& key){
	SDL_Init(SDL_INIT_EVERYTHING);
	Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096);
	string mensaje;
	Mensaje msj;
	vector<CeldaSDL*> celdasVista;
	mensaje = stream->receive();
	Json::Value tableroJson;
	tableroJson = msj.convertJson(mensaje);
	unsigned int nFil, nCol;
	nFil = tableroJson["filas"].asInt();
	std::cout << nFil << std::endl;
	nCol = tableroJson["columnas"].asInt();
	std::cout << nCol << std::endl;
	TableroSDL tableroInterfaz(nCol, nFil);
	tableroInterfaz.inicializarTablero(tableroJson);
	tableroInterfaz.createPuntajes(tableroJson["puntajes"],
			tableroInterfaz.getAncho() - SIZEEXTRA + SIZEEXTRA/4);
	MovementHandler handler(&tableroInterfaz, stream, key);
	pthread_t hilos[2];
	pthread_create(&hilos[0],NULL, enviar, (void*)&handler);
	pthread_create(&hilos[1],NULL, recibir, (void*)&handler);
	while(!handler.getTerminar()){
	}
	pthread_join(hilos[0],NULL);
	pthread_join(hilos[1],NULL);
	Mix_CloseAudio();
}

int main(int argc, char** argv){
	Gtk::Main kit(argc, argv);
	bool cerrarPrograma = false;
	if (argc == 3){
		int port = atoi(argv[2]);
		string ip = argv[1];
		ConectorCnx* connector = new ConectorCnx();
		Conexion* stream = connector->connect(ip.c_str(), port);
		TTF_Init();
		if (stream) {
			LoginInterfaz logInterfaz(stream, kit);
			if (logInterfaz.loguear()){
				//ACA METO LOBBY
				while (!cerrarPrograma){
					SDL_Init(SDL_INIT_EVERYTHING);
					Json::Value json = logInterfaz.mostrarLobby();
					stream->send(json.toStyledString());
					if (json["operacion"].asString().compare("salir") != 0){
						jugar(stream, logInterfaz.getPass());
					}else{
						cerrarPrograma = true;
					}
					SDL_Quit();
					if (!cerrarPrograma){
						connector = new ConectorCnx();
						stream = connector->connect(ip.c_str(), port);
						logInterfaz.reconnect(stream);
					}
				}
			}
		}
		TTF_Quit();
		delete stream;
	}
    return 0;
}
